<script setup lang="ts">
import { computed, ref } from 'vue';

import { useVbenDrawer } from '@vben/common-ui';
import { $t } from '@vben/locales';
import { cloneDeep } from '@vben/utils';
import type { ChangeEvent } from 'ant-design-vue/es/_util/EventInterface';
import { useVbenForm } from '#/adapter/form';
import { projectAdd, projectInfo, projectUpdate } from '#/api/clinical/project';
import type { TopicVO } from '#/api/clinical/topic/model';
import { defaultFormValueGetter, useBeforeCloseDiff } from '#/utils/popup';

import TopicTable from './components/topic-table.vue';
import { drawerSchema } from './data';
import { topicList } from '#/api/clinical/topic';
import { message, Modal } from 'ant-design-vue';

const emit = defineEmits<{ reload: [] }>();

const isUpdate = ref(false);
const title = computed(() => {
  return isUpdate.value ? $t('pages.common.edit') : $t('pages.common.add');
});

const topics = ref<TopicVO[]>([]);

const projectId = ref<string | number | undefined>();

// 更新课题
function handleChange(newTopics: TopicVO[]) {
  topics.value = newTopics;
}

const [BasicForm, formApi] = useVbenForm({
  commonConfig: {
    formItemClass: 'col-span-1',
    componentProps: {
      class: 'w-full',
    },
  },
  layout: 'vertical',
  schema: drawerSchema(),
  showDefaultActions: false,
  wrapperClass: 'grid-cols-2 gap-x-4',
});

const { onBeforeClose, markInitialized, resetInitialized } = useBeforeCloseDiff(
  {
    initializedGetter: defaultFormValueGetter(formApi),
    currentGetter: () => {
      const formValues = defaultFormValueGetter(formApi)();
      const topicIds = topics.value.map((t) => t.id) || [];
      return { ...formValues, topicIds };
    },
  },
);

const [BasicDrawer, drawerApi] = useVbenDrawer({
  // 在这里更改宽度
  class: 'w-[800px]',
  onBeforeClose,
  onClosed: handleClosed,
  onConfirm: handleConfirm,
  destroyOnClose: true,
  onOpenChange: async (isOpen) => {
    if (!isOpen) {
      return null;
    }
    drawerApi.drawerLoading(true);
    setTopics();
    const { id } = drawerApi.getData() as { id?: number | string };
    projectId.value = id;
    isUpdate.value = !!id;

    if (isUpdate.value && id) {
      const record = await projectInfo(id);
      await formApi.setValues(record);
      topics.value = await topicList({ projectId: id });
    } else {
      topics.value = [];
    }
    await markInitialized();

    drawerApi.drawerLoading(false);
  },
});
const setTopics = () => {
  formApi.updateSchema([
    {
      fieldName: 'hasTopics',
      // 关键：保持 componentProps 是一个函数，完全遵循您的写法
      componentProps: (formModel) => ({
        options: [
          { label: '是', value: '0' },
          { label: '否', value: '1' },
        ],
        // 在这个函数返回的对象中定义 onChange
        onChange: ({ target: { value } }: ChangeEvent) => {
          // 当用户选择“否”('1')，并且当前已有课题时
          if (value === '1' && topics.value.length > 0) {
            // --- 在这里加入弹窗确认 ---
            Modal.confirm({
              title: '确认操作',
              content: '切换为“否”将清空所有已添加的课题，您确定吗？',
              okText: '确定',
              cancelText: '取消',
              onOk: () => {
                // 用户确认，则清空 topics ref
                topics.value = [];
                // 同时清空表单模型中的值
                formModel.topicIds = [];
              },
              onCancel: () => {
                // 用户取消，将开关恢复为“是”
                formModel.hasTopics = '0';
              },
            });
          }
        },
      }),
    },
  ]);
};
async function handleConfirm() {
  try {
    drawerApi.lock(true);
    const { valid } = await formApi.validate();
    if (!valid) {
      return;
    }
    const data = cloneDeep(await formApi.getValues());
    data.topicIds = topics.value.map((t) => t.id) || [];
    if (data.topicIds?.length === 0 && data.hasTopics === '0') {
      message.error('课题不能为空');
      return;
    }
    await (isUpdate.value ? projectUpdate(data) : projectAdd(data));
    resetInitialized();
    emit('reload');
    drawerApi.close();
  } catch (error) {
    console.error(error);
  } finally {
    drawerApi.lock(false);
  }
}

async function handleClosed() {
  await formApi.resetForm();
  topics.value = [];
  resetInitialized();
}
</script>

<template>
  <BasicDrawer :title="title">
    <BasicForm>
      <template #topicIds>
        <div class="h-[425px] w-full">
          <TopicTable
            ref="topicTableRef"
            :projectId="projectId"
            :topics="topics"
            @change="handleChange"
          />
        </div>
      </template>
    </BasicForm>
  </BasicDrawer>
</template>
